package view;

import java.io.IOException;
import javax.microedition.lcdui.game.GameCanvas;
import model.event.RandomEventGenerator;

/**
 * Provides the basis for a game user interface for the Drug Wars system. This class monitors
 * the keypad for inputs from the user and processes the events that have occurred.
 *
 * @author rhaq
 * @version 1.00 2009-05-05 Initial submission.
 */
public class DWGameCanvas extends GameCanvas implements Runnable
{
	/** Delay used to give thread consistency. */
	public static final long DELAY = 20;

	/** Processes the events that are generated by the user on the keypad. */
	private GraphicsIO io;

	/** Is there a game in progress? */
	private static Boolean playing;

	private RandomEventGenerator r;


	/**
	 * Creates a new instance of this class and sets up the event processors as well as setting
	 * the status of the game to be initialized.
	 * @throws IOException If any of the required graphics cannot be loaded. 
	 */
	public DWGameCanvas() throws IOException
	{
		super(true); // suppress key events because we will be handling the key events ourselves instead of having a listener

		this.io = new GraphicsIO( getGraphics(), getWidth(), getHeight() );
		playing = new Boolean(true);
		this.r = new RandomEventGenerator( playing, io.getEventLayer(), io.getUserLayer() );
	}



	/**
	 * Monitors the keypad for any inputs received (specifically monitors the up, down, left,
	 * right keys on the keypad for movements). Any input that is received is then processed.
	 * Note that it is not guaranteed that the order that the keys were pressed will result in
	 * the order they will be processed (due to the slight delay that occurs in the thread).
	 */
	private void input()
	{
		int keyStates = getKeyStates();

		boolean leftPressed = isPressed(keyStates, LEFT_PRESSED);;
		boolean rightPressed = isPressed(keyStates, RIGHT_PRESSED);;
		boolean upPressed = isPressed(keyStates, UP_PRESSED);;
		boolean downPressed = isPressed(keyStates, DOWN_PRESSED);;
		boolean updateNeeded = leftPressed || rightPressed || upPressed || downPressed;

		if (updateNeeded)
		{
			if (leftPressed)
				io.pressedLeft();

			if (rightPressed)
				io.pressedRight();

			if (downPressed)
				io.pressedDown();

			if (upPressed)
				io.pressedUp();
		}
		
		update();
	}


	/**
	 * Determines if the specified key was inputted.
	 * @param keyStates The state of all the keys on the keypad.
	 * @param key The key to determine if it was pressed.
	 * @return true if the specified key was pressed, false otherwise.
	 */
	private static final boolean isPressed(int keyStates, final int key)
	{
		return (keyStates & key) != 0;
	}


	/* (non-Javadoc)
	 * @see java.lang.Runnable#run()
	 */
	public void run()
	{
		new Thread(r).start();
		update();

		while ( playing.booleanValue() )
		{
			input();

			try
			{
				Thread.sleep(DELAY);
			}

			catch (InterruptedException ie)
			{
				ie.printStackTrace();
			}
		}
	}


	/**
	 * Updates the view so that changes can be displayed.
	 */
	private void update()
	{
		io.updateGraphics();
		flushGraphics();		
	}
}